package com.ybear.ybutils.utils

import android.content.ActivityNotFoundException
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import com.ybear.ybutils.utils.AppUtil.getPackageName
import org.json.JSONObject
import java.net.URLEncoder
import java.util.Locale
import java.util.concurrent.atomic.AtomicBoolean

/**
 * 跳转应用详情页
 * 打开 Google，华为、小米，VIVO，OPPO，三星等机型的详情页面
 */
object StartStore {
    private const val KEY_PKG_NAME = "a"
    private const val KEY_URI = "b"
    private const val KEY_PAGE = "c"
    private const val KEY_DETAIL_CN = "x"
    private const val KEY_DETAIL_GLOBAL = "y"

    private data class StoreInfo(
        val packageName: String,
        val uri: Uri,
        val page: String? = null
    )

    private enum class StoreKey(
        val jsonKey: String,
        val manufacturers: List<String>
    ) {
        GG( "a", emptyList() ),
        MI( "b", listOf( "xiaomi" ) ),
        HW( "c", listOf( "huawei" ) ),
        VIVO( "d", listOf( "vivo" ) ),
        OPPO( "e", listOf( "oppo", "heytap" ) ),
        SAMSUNG( "f", listOf("samsung" ) ),
        TX( "g", listOf("tencent", "qq" ) )
    }

    private open class StoreDataHelper {
        companion object {
            @JvmStatic private val instance by lazy { StoreDataHelper() }
            @JvmStatic fun get(): StoreDataHelper = instance
        }

        // Base64 加密的 JSON 字符串，包含 a-g 所有商店配置
        // {"a": {"a": "market://details?id=","b": "https://play.google.com/store/apps/details?id="},"b": {"a": "com.xiaomi.market","b": "mimarket://details?id=","c": "http://app.mi.com/detail/","x": "https://app.mi.com/details?id=","y": "https://global.app.mi.com/details?id="},"c": {"a": "com.huawei.appmarket","b": "appmarket://details?id=","x": "https://appgallery.huawei.com/app/","y": "https://appgallery.cloud.huawei.com/appdl/"},"d": {"a": "com.bbk.appstore","b": "vivomarket://details?id=","c": "http://a.app.qq.com/o/simple.jsp?pkgname=","x": "https://api.vivo.com.cn/app/detail/","y": "https://global.app.mi.com/details?id="},"e": {"a": "com.heytap.market","b": "oppomarket://details?packagename=","x": "https://heytap.market/detail?packageName=","y": "https://play.google.com/store/apps/details?id="},"f": {"a": "com.sec.android.app.samsungapps","b": "samsungapps://ProductDetail/","x": "https://apps.samsung.com/appquery/appDetail.as?appPackageName=","y": "https://play.google.com/store/apps/details?id="},"g": {"a": "com.tencent.android.qqdownloader","b": "mqqopensdkapi://bizAgent/qm/qr?url=","c": "http://a.app.qq.com/o/simple.jsp?pkgname=","x": "https://app.mi.com/details?id=","y": "https://global.app.mi.com/details?id="}}
        private val data = "eyJhIjogeyJhIjogIm1hcmtldDovL2RldGFpbHM/aWQ9IiwiYiI6ICJodHRwczovL3BsYXkuZ29vZ2xlLmNvbS9zdG9yZS9hcHBzL2RldGFpbHM/aWQ9In0sImIiOiB7ImEiOiAiY29tLnhpYW9taS5tYXJrZXQiLCJiIjogIm1pbWFya2V0Oi8vZGV0YWlscz9pZD0iLCJjIjogImh0dHA6Ly9hcHAubWkuY29tL2RldGFpbC8iLCJ4IjogImh0dHBzOi8vYXBwLm1pLmNvbS9kZXRhaWxzP2lkPSIsInkiOiAiaHR0cHM6Ly9nbG9iYWwuYXBwLm1pLmNvbS9kZXRhaWxzP2lkPSJ9LCJjIjogeyJhIjogImNvbS5odWF3ZWkuYXBwbWFya2V0IiwiYiI6ICJhcHBtYXJrZXQ6Ly9kZXRhaWxzP2lkPSIsIngiOiAiaHR0cHM6Ly9hcHBnYWxsZXJ5Lmh1YXdlaS5jb20vYXBwLyIsInkiOiAiaHR0cHM6Ly9hcHBnYWxsZXJ5LmNsb3VkLmh1YXdlaS5jb20vYXBwZGwvIn0sImQiOiB7ImEiOiAiY29tLmJiay5hcHBzdG9yZSIsImIiOiAidml2b21hcmtldDovL2RldGFpbHM/aWQ9IiwiYyI6ICJodHRwOi8vYS5hcHAucXEuY29tL28vc2ltcGxlLmpzcD9wa2duYW1lPSIsIngiOiAiaHR0cHM6Ly9hcGkudml2by5jb20uY24vYXBwL2RldGFpbC8iLCJ5IjogImh0dHBzOi8vZ2xvYmFsLmFwcC5taS5jb20vZGV0YWlscz9pZD0ifSwiZSI6IHsiYSI6ICJjb20uaGV5dGFwLm1hcmtldCIsImIiOiAib3Bwb21hcmtldDovL2RldGFpbHM/cGFja2FnZW5hbWU9IiwieCI6ICJodHRwczovL2hleXRhcC5tYXJrZXQvZGV0YWlsP3BhY2thZ2VOYW1lPSIsInkiOiAiaHR0cHM6Ly9wbGF5Lmdvb2dsZS5jb20vc3RvcmUvYXBwcy9kZXRhaWxzP2lkPSJ9LCJmIjogeyJhIjogImNvbS5zZWMuYW5kcm9pZC5hcHAuc2Ftc3VuZ2FwcHMiLCJiIjogInNhbXN1bmdhcHBzOi8vUHJvZHVjdERldGFpbC8iLCJ4IjogImh0dHBzOi8vYXBwcy5zYW1zdW5nLmNvbS9hcHBxdWVyeS9hcHBEZXRhaWwuYXM/YXBwUGFja2FnZU5hbWU9IiwieSI6ICJodHRwczovL3BsYXkuZ29vZ2xlLmNvbS9zdG9yZS9hcHBzL2RldGFpbHM/aWQ9In0sImciOiB7ImEiOiAiY29tLnRlbmNlbnQuYW5kcm9pZC5xcWRvd25sb2FkZXIiLCJiIjogIm1xcW9wZW5zZGthcGk6Ly9iaXpBZ2VudC9xbS9xcj91cmw9IiwiYyI6ICJodHRwOi8vYS5hcHAucXEuY29tL28vc2ltcGxlLmpzcD9wa2duYW1lPSIsIngiOiAiaHR0cHM6Ly9hcHAubWkuY29tL2RldGFpbHM/aWQ9IiwieSI6ICJodHRwczovL2dsb2JhbC5hcHAubWkuY29tL2RldGFpbHM/aWQ9In19"
        private val initialized = AtomicBoolean( false )
        private val storeMap = mutableMapOf<StoreKey, StoreInfo>()

        fun init(context: Context): StoreDataHelper {
            if ( initialized.get() ) return this
            initialized.set( true )

            val pkg = context.packageName
            val json = JSONObject( Base64Utils.decodeBase64String( data ) )
            StoreKey.values().forEach { sk ->
                json.optJSONObject(sk.jsonKey)?.apply {
                    val pkgName = getString( KEY_PKG_NAME )
                    val scheme = getString( KEY_URI )
                    val pageUrl = when ( sk ) {
                        StoreKey.TX -> optString( KEY_PAGE, "" ) + pkg
                        StoreKey.MI -> optString( KEY_PAGE, "" )
                        else -> null
                    }
                    val uriStr = if ( sk == StoreKey.TX )
                        scheme + URLEncoder.encode( pageUrl, "UTF-8" )
                    else scheme + pkg

                    storeMap[ sk ] = StoreInfo(
                        packageName = pkgName,
                        uri = Uri.parse( uriStr ),
                        page = pageUrl
                    )
                }
            }
            return this
        }

        fun storeInfo(sk: StoreKey): StoreInfo? = storeMap[ sk ]
        fun storeInfoList(): List<StoreInfo> = storeMap.values.toList()
    }

    @JvmOverloads
    @JvmStatic
    fun start(
        context: Context?,
        chooserTitle: String? = null,
        packageName: String? = context?.let { getPackageName( it ) },
    ): Boolean {
        context ?: return false
        val pkg = packageName ?: context.packageName
        val helper = StoreDataHelper.get().init( context )
        val pm = context.packageManager

        val mainIntent = helper.storeInfo( StoreKey.GG )?.uri?.let {
            Intent( Intent.ACTION_VIEW, it ).apply { addFlags( Intent.FLAG_ACTIVITY_NEW_TASK ) }
        }

        val installed = helper.storeInfoList().filter {
            try { pm.getPackageInfo(it.packageName, 0); true } catch (_: Exception) { false }
        }.map {
            Intent( Intent.ACTION_VIEW, it.uri ).apply {
                setPackage( it.packageName )
                addFlags( Intent.FLAG_ACTIVITY_NEW_TASK )
            }
        }

        val webPlay = helper.storeInfo( StoreKey.GG )?.uri?.let {
            Intent( Intent.ACTION_VIEW, it ).apply { addFlags( Intent.FLAG_ACTIVITY_NEW_TASK ) }
        }

        val intents = mutableListOf<Intent>().apply {
            mainIntent?.let { add( it ) }
            addAll( installed )
            webPlay?.let { add( it ) }
        }

        return try {
            val chooser = Intent.createChooser(
                intents.removeAt( 0 ),
                chooserTitle ?: ""
            ).apply {
                putExtra( Intent.EXTRA_INITIAL_INTENTS, intents.toTypedArray() )
            }
            context.startActivity(chooser)
            true
        } catch (e: ActivityNotFoundException) {
            try {
                val json = JSONObject(
                    Base64Utils.decodeBase64String(
                        StoreDataHelper.get().javaClass
                            .getDeclaredField( "data" ).apply { isAccessible = true }
                            .get( StoreDataHelper.get() ) as String
                    )
                )
                val manu = Build.MANUFACTURER.lowercase( Locale.ROOT )
                val sk = StoreKey.values()
                    .firstOrNull { sk -> sk.manufacturers.any { manu.contains(it) } }
                    ?: StoreKey.GG

                val vendor = json.getJSONObject( sk.jsonKey )
                val field = if ( Locale.getDefault().country == "CN" )
                    KEY_DETAIL_CN
                else
                    KEY_DETAIL_GLOBAL
                val url = vendor.getString(field) + pkg
                context.startActivity( Intent( Intent.ACTION_VIEW, Uri.parse( url ) ).apply {
                    addFlags( Intent.FLAG_ACTIVITY_NEW_TASK )
                })
                true
            } catch (_: Exception) {
                false
            }
        }
    }
}